#ifndef __NIX_THREAD_H__
#define __NIX_THREAD_H__

#include <pthread.h>

#include "../non_copyable.h"
#include "../callback.h"
#include "../exceptions.h"

namespace Boss
{

  BOSS_DECLARE_RUNTIME_EXCEPTION(Thread)

  namespace Internal
  {

    class ThreadImpl
      : private NonCopyable
    {
    public:
      ThreadImpl(ICallbackPtr callback)
        : Callback(callback)
        , Thread(0)
      {
        if (!Callback.Get())
          throw ThreadException("Empty callback");
        if (pthread_create(&Thread, 0, &ThreadImpl::ThreadProc, Callback.Get()))
          throw ThreadException("Can't create thread");
      }
      ~ThreadImpl()
      {
        pthread_join(Thread, 0);
        pthread_detach(Thread);
      }

    private:
      ICallbackPtr Callback;
      pthread_t Thread;

      static void* ThreadProc(void *param)
      {
        reinterpret_cast<ICallback *>(param)->Do();
        return 0;
      }
    };

  }

  typedef Internal::ThreadImpl Thread;

}

#endif  // !__NIX_THREAD_H__
